
#include	<stdio.h>

#include	"zsocket/microtime.hpp"

namespace	zsocket
{

microtime_t	microtime( void )
{
	struct	timeval	tm;
	
	gettimeofday( &tm, NULL );
	
	return	tm;
}

microtime_t::microtime_t()
	:	m_sec(0), m_usec(0)
{
}

microtime_t::microtime_t(const struct timeval& rhs)
	:	m_sec(rhs.tv_sec), m_usec(rhs.tv_usec)
{
}

microtime_t&
microtime_t::operator=( int iSeconds )
{
	if ( iSeconds >= 0 ) {
		this->m_sec = iSeconds;
		this->m_usec = 0;
	}
	
	return	*this;
}

microtime_t&
microtime_t::operator-=( const microtime_t& rhs )
{
	this->m_usec -= rhs.m_usec;
	if ( this->m_usec < 0 ) {
		this->m_sec -= (rhs.m_sec + 1);
		this->m_usec += 1000000;
	}
	else {
		this->m_sec -= rhs.m_sec;
	}
	
	return	*this;
}

microtime_t&
microtime_t::operator+=( const microtime_t& rhs )
{
	this->m_usec += rhs.m_usec;
	if ( this->m_usec >= 1000000 ) {
		this->m_sec += (rhs.m_sec + 1);
		this->m_usec -= 1000000;
	}
	else {
		this->m_sec += rhs.m_sec;
	}
	
	return	*this;
}

microtime_t
microtime_t::operator-( const microtime_t& rhs )
{
	microtime_t	result;
	
	result.m_usec = this->m_usec - rhs.m_usec;
	if ( result.m_usec < 0 ) {
		result.m_sec = this->m_sec - (rhs.m_sec + 1);
		result.m_usec += 1000000;
	}
	else {
		result.m_sec = this->m_sec - rhs.m_sec;
	}
	
	return	result;
}

microtime_t
microtime_t::operator+( const microtime_t& rhs )
{
	microtime_t	result;
	
	result.m_usec = this->m_usec + rhs.m_usec;
	if ( result.m_usec >= 1000000 ) {
		result.m_sec = this->m_sec + (rhs.m_sec + 1);
		result.m_usec -= 1000000;
	}
	else {
		result.m_sec = this->m_sec + rhs.m_sec;
	}
	
	return	result;
}

microtime_t&
microtime_t::operator-=( int seconds )
{
	this->m_sec -= seconds;
	
	return	*this;
}

microtime_t&
microtime_t::operator+=( int seconds )
{
	this->m_sec += seconds;
	
	return	*this;
}

microtime_t
microtime_t::operator-( int seconds )
{
	microtime_t	result;
	
	result.m_usec = this->m_usec;
	result.m_sec = this->m_sec - seconds;
	
	return	result;
}

microtime_t
microtime_t::operator+( int seconds )
{
	microtime_t	result;
	
	result.m_usec = this->m_usec;
	result.m_sec = this->m_sec + seconds;
	
	return	result;
}

microtime_t::operator double()
{
	double	d = this->m_sec + (this->m_usec / 1000000.0);
	
	return	d;
}

bool
microtime_t::operator<( const microtime_t& rhs )
{
    if (this->m_sec < rhs.m_sec) {
        return    true;
    }
    else if ((this->m_sec == rhs.m_sec) && (this->m_usec < rhs.m_usec)) {
        return    true; 
    }
    
    return    false;
}

bool
microtime_t::operator>( const microtime_t& rhs )
{
    if (this->m_sec > rhs.m_sec) {
        return    true;
    }
    else if ((this->m_sec == rhs.m_sec) && (this->m_usec > rhs.m_usec)) {
        return    true; 
    }
    
    return    false;
}

bool
microtime_t::operator==( const microtime_t& rhs )
{
    if ((this->m_sec == rhs.m_sec) && (this->m_usec == rhs.m_usec)) {
        return    true; 
    }
    
    return    false;
}

const char*
microtime_t::c_str( void )
{
#ifdef	__FreeBSD__
	int	iSize = snprintf( m_szBuf, sizeof(m_szBuf) - 1, "%u.%06lu", this->m_sec, this->m_usec );
#else
	int	iSize = snprintf( m_szBuf, sizeof(m_szBuf) - 1, "%lu.%06lu", this->m_sec, this->m_usec );
#endif

	m_szBuf[ iSize ] = '\0';	
	
	return	m_szBuf;
}

}	// namespace zsocket 
